/*
 * Copyright (c) 2017, www.zm0618.com All Rights Reserved..
 */

package com.light.hessian.remoting.client.balance;

import com.light.hessian.provider.config.ProviderStatus;
import com.light.hessian.provider.slot.ProviderStatusSlot;
import com.light.hessian.provider.slot.ProviderStatusSlotHolder;
import com.light.hessian.provider.slot.exception.SlotSelectException;

import java.util.List;

/**
 * Created by zhaojun on 2017/02/12.
 */
public abstract class BaseBalancer {

    protected  volatile ProviderStatusSlot[] statusSlots;

    protected  volatile ProviderStatusSlotHolder statusSlotHolder;

    public BaseBalancer() {
    }

    public BaseBalancer(List<ProviderStatusSlot> statusSlots) {
        setProviderStatusSlots(statusSlots);
    }

    public void setProviderStatusSlots(List<ProviderStatusSlot> statusSlots) {
        int len = statusSlots.size();
        ProviderStatusSlot[] _statusSlots = new ProviderStatusSlot[len];
        statusSlots.toArray(_statusSlots);
        this.statusSlots=_statusSlots;
    }

    public void refreshSlots(){
        List<ProviderStatusSlot> statusList = this.statusSlotHolder.getProviderStatusSlots();
        setProviderStatusSlots(statusList);
    }
    public ProviderStatusSlotHolder getStatusSlotHolder() {
        return statusSlotHolder;
    }

    public void setStatusSlotHolder(ProviderStatusSlotHolder statusSlotHolder) {
        this.statusSlotHolder = statusSlotHolder;
    }


    public ProviderStatusSlot failback(int index, ProviderStatusSlot[] cStatusSlots) {

        ProviderStatusSlot statusSlot=null;
        int len=cStatusSlots.length;
        if (index==len-1){
            for ( int i=0;i<len-1;i++){
                statusSlot = cStatusSlots[i];
                if (statusSlot.getStatus()== ProviderStatus.UP){
                    return statusSlot;
                }
            }
        }else{
            int i=index;
            int j=i+1;
            for(;j<len;j++){
                statusSlot = cStatusSlots[j];
                if (statusSlot.getStatus()==ProviderStatus.UP){
                    return statusSlot;
                }
            }
            i--;
            for (;i>=0;i--){
                statusSlot = cStatusSlots[i];
                if (statusSlot.getStatus()==ProviderStatus.UP){
                    return statusSlot;
                }
            }
        }

        throw new SlotSelectException("All Provider-nodes are down!!!!!!");

    }

    public abstract String getBalancerName() ;
    public abstract ProviderStatusSlot select();
}
